import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

public class Otimo extends Strategy {

	HashMap<Integer, PaginaOtimo> hashChamadas;
	HashMap<Integer, Integer> memoria;

	Otimo(int numFrames, List<Request> operacoes) {
		super(numFrames, operacoes);

		hashChamadas = new HashMap<Integer, PaginaOtimo>();
		memoria = new HashMap<Integer, Integer>();
		gerarChamadas();
	}

	void run() {
		int momento = 0;
		for (Request op : requests) {
			if (memoria.containsKey(op.value)) {
				hit++;
			} else {
				if (memoria.size() >= frameSize) {
					Set<Integer> chaves = memoria.keySet();
					int removed = -1;
					int maior = -1;
					PaginaOtimo paginaOtimo = null;
					for (Integer chave : chaves) {
						if (chave != null) {
							int pagina = memoria.get(chave);
							paginaOtimo = hashChamadas.get(pagina);
							int valor = 0;
							try {
								Node<Integer> nodeAchado = paginaOtimo.getChamadas()
										.getNodeBiggerThan(new Integer(momento));
								if (nodeAchado == null) {
									removed = chave;
									break;
								} else {
									valor = nodeAchado.value;
								}
							} catch (ParseException e) {
								e.printStackTrace();
							}
							if (maior < valor) {
								maior = valor;
								removed = chave;
							}
						}
					}
					memoria.remove(removed);
				}

				memoria.put(op.value, op.value);
			}
			momento++;
		}
	}

	private void gerarChamadas() {
		int i = 0;
		PaginaOtimo pagina = null;
		for (Request op : requests) {
			if (hashChamadas.containsKey(op.value)) {
				pagina = hashChamadas.get(op.value);
				pagina.adicionarChamada(i);
			} else {
				pagina = new PaginaOtimo(op.value);
				pagina.adicionarChamada(i);
				hashChamadas.put(op.value, pagina);
			}
			i++;
		}
	}

	static String getName() {
		return "Otimo";
	}

	public void reset() {
		hit = 0;
		memoria = new HashMap<Integer, Integer>();

		Set<Integer> chaves = hashChamadas.keySet();
		for (Integer chave : chaves) {
			if (chave != null) {
				hashChamadas.get(chave).zerar();
			}
		}
	}
}
